package com.treasure.mall.biz.service.core.blacklist.impl;

import com.treasure.mall.biz.base.AbstractSearchableCrudService;
import com.treasure.mall.biz.base.SpecificationAndSort;
import com.treasure.mall.biz.dto.BaseSaveDTO;
import com.treasure.mall.biz.dto.BaseSearchDTO;
import com.treasure.mall.biz.dto.blacklist.BlacklistSaveDTO;
import com.treasure.mall.biz.dto.condition.BlacklistSearchCondition;
import com.treasure.mall.biz.entity.blacklist.BlacklistPO;
import com.treasure.mall.biz.entity.blacklist.BlacklistPO_;
import com.treasure.mall.biz.entity.user.UserPO;
import com.treasure.mall.biz.entity.user.UserPO_;
import com.treasure.mall.biz.repository.blacklist.BlacklistRepository;
import com.treasure.mall.biz.service.core.blacklist.BlacklistService;
import com.treasure.mall.biz.service.core.user.UserService;
import com.treasure.mall.zbq.common.base.ApiResult;
import com.treasure.mall.zbq.common.base.ResultCodeEnum;
import com.treasure.mall.zbq.common.exception.ApiException;
import com.treasure.mall.zbq.common.ienum.SystemEnums;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 
 * <p>
 * +---------------------------------------------------------
 * * @package: com.treasure.mall.biz.service.core.blacklist.impl
 * * @author: guomw (guomwchen@foxmail.com)
 * * @date: 2020/9/23 2:32 下午
 * * @since: V1.0.0
 * +---------------------------------------------------------
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 * 
 */
@Service
public class BlacklistServiceImpl extends AbstractSearchableCrudService<BlacklistPO, Long> implements BlacklistService {
    private BlacklistRepository blacklistRepository;
    @Autowired
    private UserService userService;

    protected BlacklistServiceImpl(BlacklistRepository repository) {
        super(repository);
        blacklistRepository = repository;
    }

    @Override
    protected SpecificationAndSort<BlacklistPO> specificationAndSort(BaseSearchDTO searchDTO) {
        BlacklistSearchCondition condition = (BlacklistSearchCondition) searchDTO;
        Specification<BlacklistPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(cb.equal(root.get(BlacklistPO_.deleted), false));
            predicates.add(cb.equal(root.get(BlacklistPO_.disable), true));
            if (StringUtils.isNotBlank(condition.getMobile())) {
                predicates.add(cb.or(
                        cb.like(root.get(BlacklistPO_.user).get(UserPO_.mobile), likeLeft(condition.getMobile())),
                        cb.like(root.get(BlacklistPO_.user).get(UserPO_.nickName), likeAll(condition.getMobile())))
                );
            }
            if (condition.getBlacklistType() != null) {
                predicates.add(cb.equal(root.get(BlacklistPO_.blacklistType), condition.getBlacklistType()));
            }

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return new SpecificationAndSort<>(specification, sort);
    }

    /**
     * 判断是否
     *
     * @param userId        用户ID
     * @param blacklistType 黑名单类型
     * @return
     */
    @Override
    public boolean checkByUserId(Long userId, SystemEnums.BlacklistType blacklistType) {
        return blacklistRepository.countByBlacklistTypeAndUser_UserId(blacklistType, userId) > 0;
    }

    @Override
    public BlacklistPO save(BaseSaveDTO saveDTO) {
        BlacklistSaveDTO dto = (BlacklistSaveDTO) saveDTO;
        UserPO userPO = userService.findByUsername(dto.getMobile());
        if (userPO == null) {
            throw new ApiException(ApiResult.error(ResultCodeEnum.ILLEGAL_STATE, "无效手机号码"));
        }
        BlacklistPO po = new BlacklistPO();
        po.setBlacklistType(dto.getBlacklistType());
        po.setUser(userService.findByUsername(dto.getMobile()));
        po.setDisable(true);
        po.setCreateTime(LocalDateTime.now());
        save(po);
        return po;
    }
}
